Fix grammar rules containing or pertaining to bounds#2257
Conversation
| r[type.trait-object.syntax] | ||
| ```grammar,types | ||
| TraitObjectType -> `dyn`? TypeParamBounds | ||
| TraitObjectType -> TypeParamBounds | `dyn` TypeParamBounds? |
There was a problem hiding this comment.
Due to this grammar rule, TypeParamBounds (now: Bounds) must remain non-empty.
4200b2e to
7b807ac
Compare
This comment has been minimized.
This comment has been minimized.
7b807ac to
e8c2309
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
e8c2309 to
9f6b416
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
`struct T<'a:> where 'a:;` is syntactically valid.
| r[type.impl-trait.syntax] | ||
| ```grammar,types | ||
| ImplTraitType -> `impl` Bounds | ||
| ImplTraitType -> `impl` Bounds? |
There was a problem hiding this comment.
Can we add a rule somewhere in this chapter that specifies at least one trait must be listed in the bounds? I believe this corresponds to the AtLeastOneTrait error.
| r[type.trait-object.syntax] | ||
| ```grammar,types | ||
| TraitObjectType -> `dyn`? Bounds | ||
| TraitObjectType -> Bounds | `dyn` Bounds? |
There was a problem hiding this comment.
Similar to my other comment, can we have a rule to say at least one trait is required?
I'm not sure if it makes sense to combine that into type.trait-object.constraint or to have a separate rule just below that.
| r[type.trait-object.syntax-edition2018] | ||
| > [!EDITION-2018] | ||
| > In the 2015 edition, if the first bound of the trait object is a path that starts with `::`, then the `dyn` will be treated as a part of the path. The first path can be put in parenthesis to get around this. As such, if you want a trait object with the trait `::your_module::Trait`, you should write it as `dyn (::your_module::Trait)`. | ||
| > In the 2015 edition, `dyn` must be followed by [PathIdentSegment][grammar-PathIdentSegment], [LIFETIME_OR_LABEL][grammar-LIFETIME_OR_LABEL], `for`, `(` or `?` to be interpreted as the start of a trait object type. Otherwise, it will be interpreted as a regular identifier. |
There was a problem hiding this comment.
The link destinations aren't required here, since definitions for the rule names are generated automatically.
| > In the 2015 edition, `dyn` must be followed by [PathIdentSegment][grammar-PathIdentSegment], [LIFETIME_OR_LABEL][grammar-LIFETIME_OR_LABEL], `for`, `(` or `?` to be interpreted as the start of a trait object type. Otherwise, it will be interpreted as a regular identifier. | |
| > In the 2015 edition, `dyn` must be followed by [PathIdentSegment], [LIFETIME_OR_LABEL], `for`, `(` or `?` to be interpreted as the start of a trait object type. Otherwise, it will be interpreted as a regular identifier. |
At least since PR rust-lang/rust#39158 (2017) bounds are intentionally always optional after "bound heralds" (
:,impl,dyn). However, the Reference didn't reflect this fact everywhere. This PR rectifies this.For example reference@master considers the following snippets to be syntactically ill-formed which directly contradicts rustc:
type T: ;,type T: where;,type T: = U;T<U: >,T<U<V>: >(as briefly mentioned in PR Fix the grammar of generic arguments #2247)impl,fn() -> impldyn,fn() -> dynstruct T<'a:> where 'a:;Furthermore, the edition disclaimer for trait object types is incomplete / imprecise / inaccurate:
It states that token sequence
dyn::will be interpreted as the start of a path in Rust 2015 which is correct in isolation but far from complete in context. Per argumentum e contrario, it would wrongly imply that in Rust 2015 the following snippets all contain (bare) trait object types:type T = dyn;,type T = (dyn);,type T = [dyn];type T = dyn<>;,type T = dyn<()>;,type T = dyn<<T>::S>;To address this, I've changed the note to use an exhaustive and positive listing of tokens. The follow set is {PathIdentSegment, LIFETIME_OR_LABEL,
for,(,?} as per rustc'scan_begin_dyn_bound_in_edition_2015.